package bgu.dcr.tp.api;

import bgu.dcr.tp.utils.EventListeners;
import java.sql.Time;
import java.util.Collection;

/**
 * The world is a container for its simulation objects and other general
 * information. T is a collection of parameters containing info about the world.
 *
 * @author Shl
 */
public interface World {

    EventListeners<WorldListener> getListeners();
    
    /**
     * An index is like a "point"/coordinate/id of something in the world.
     * inserts new world data by index, or updates the current data for that
     * index and type. notice that data could also be an agent (which is
     * attached to this index). notice that index -1 will be a special system
     * point.
     *
     * @param index
     * @param data
     */
    public void addData(int index, Object data);

    /**
     * inserts a service of a specific type.
     */
    public void addService(Object data);

    /**
     * get all behaviours defined in this world.
     *
     * @return
     */
    public Collection<Behavior> getBehaviors();

    public void addBehavior(Behavior behavior);

    public void removeBehavior(Behavior behavior);

    /**
     * An index is like a "point"/coordinate/id of something in the world. get
     * world data by index and type. returns null if non existent. notice that
     * data could also be an agent. you can get an index of something from a
     * relevant service.
     *
     * @return data by type. index -1 will yield the data in the special system
     * point. (could be for example, all the agents, all statistics... and so
     * on)
     */
    public <T> T getData(int index, Class<T> type);

    /**
     * Get a service of a specific type of objects. for example, RoadManager is
     * a service that knows all the information about roads in the world. a
     * clock service knows the time, etc...
     *
     * @return data by type.
     */
    public <T> T getService(Class<T> type);

    Collection<Integer> getAllIds();

    public interface WorldListener {

        void onDataAdded(World source, int index, Object data);

        void onIndexAdded(World source, int index);

        void onBehaviorAdded(World source, Behavior b);

        void onBehaviorRemoved(World source, Behavior b);
    }
}
